Event Loop (1/4)
Explain the event loop.
    The event loop enables Node.js to perform non-blocking I/O operations When Node.js starts, it initialises the event loop, to process the input script which may make async API calls, schedule timers, call process.nextTick()
    • There are a total of six phases and each phase has a FIFO queue of callbacks to execute.
    • When the event loop enters a given phase, it will perform any operations specific to that phase, then execute callbacks in that phase's queue until the queue has been exhausted or the maximum number of callbacks has been executed.
    • When the queue has been exhausted or the callback limit is reached, the event loop will move to the next phase, and so on.
    Phases Overview
    • Timers phase: This phase executes callbacks scheduled by setTimeout() and setInterval().
    • Pending callbacks phase: executes I/O callbacks deferred to the next loop iteration.
    • Idle, prepare phase: only used internally.
    • Poll phase: retrieve new I/O events, execute I/O related callbacks (almost all except close callbacks, the ones scheduled by timers, and setImmediate()), node will block here when appropriate.
    • Check phase: setImmediate() callbacks are invoked here.
    • Close callbacks phase: some close callbacks, e.g. socket.on('close', ...).
    Timer phase
    • A timer specifies the threshold after which a provided callback may be executed rather than the exact time we want it to be executed.
    • Timer callbacks will run as early as they can be scheduled after the specified amount of time has passed; however, Operating System scheduling or the running of other callbacks may delay them.
    • This is the first phase as some timers may have their callbacks pending for execution and thus need to be executed first.
    Pending callbacks phase
    • The event loop processes some polled events within the poll phase and defers specific events to the pending phase in the next loop iteration.
    • It's responsible for executing callback functions that were registered to be called when certain events or asynchronous operations are completed.
    • This phase executes callbacks for some system operations such as types of TCP errors. For example, if a TCP socket receives ECONNREFUSED when attempting to connect, some *nix systems want to wait to report the error. This will be queued to execute in the pending callbacks phase.
    • Asynchronous Operations: Asynchronous operations often involve I/O (Input/Output) tasks like reading files, making HTTP requests, or handling timers. When these operations are initiated, they typically don't block the main thread but instead register callbacks to be executed when they are completed.
    Idle, prepare phase
    • The event loop uses the idle, prepare phase for internal housekeeping operations. It doesn’t have a direct effect on the Node.js code you write.
    Poll phase
    • The poll phase has two main functions: Calculating how long it should block and poll for I/O, then Processing events in the poll queue.

    Once the poll queue is empty the event loop will check for timers whose time thresholds have been reached. If one or more timers are ready, the event loop will wrap back to the timers phase to execute those timers' callbacks.

    When the event loop enters the poll phase and there are no timers scheduled, one of two things will happen:
    • If the poll queue is not empty, the event loop will iterate through its queue of callbacks executing them synchronously until either the queue has been exhausted, or the system-dependent hard limit is reached.
    If the poll queue is empty, one of two things will happen:
    • If scripts have been scheduled by setImmediate(), the event loop will end the poll phase and continue to the check phase to execute those scheduled scripts.
    • If scripts have not been scheduled by setImmediate(), the event loop will wait for callbacks to be added to the queue, and then execute them immediately.
    Check phase
    • This phase allows us to execute callbacks immediately after completing the poll phase. If the poll phase becomes idle and scripts have been queued with setImmediate(), the event loop may continue to the check phase rather than waiting.
    • setImmediate() is a special timer that runs in a separate phase of the event loop. It uses a libuv API that schedules callbacks to execute after the poll phase has been completed.
    • As the code is executed, the event loop will eventually hit the poll phase where it will wait for an incoming connection, request, etc. However, if a callback has been scheduled with setImmediate() and the poll phase becomes idle, it will end and continue to the check phase rather than waiting for poll events.
    • The event loop executes multiple setImmediate callbacks in the order in which they are created.
    Close callbacks phase
    • If a socket or handle is closed abruptly (e.g. socket.destroy()), the 'close' event will be emitted in this phase. Otherwise, it will be emitted via process.nextTick().